/*************
**
** Project:      stopwatch
** File info:    $Id: mainwindow.cpp 24 2012-05-04 10:48:01Z Kuzma.Shapran@gmail.com $
** Author:       Copyright (C) 2011 Kuzma Shapran <Kuzma.Shapran@gmail.com>
** License:      GPLv3
**
**  This file is part of Stopwatch.
**
**  Stopwatch is free software: you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation, either version 3 of the License, or
**  (at your option) any later version.
**
**  Stopwatch is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with Stopwatch.  If not, see <http://www.gnu.org/licenses/>.
**
*************/

#include "mainwindow.hpp"

#include <QtGui/QMenu>

#ifdef Q_OS_SYMBIAN
#include <QtGui/QDesktopWidget>
#else
#include <QtGui/QResizeEvent>
#endif


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , Ui::MainWindow()
{
    setupUi(this);

    actionExit     ->setIcon(style()->standardIcon(static_cast<QStyle::StandardPixmap>(QStyle::SP_CustomBase + 0x07))); // back
    actionStopWatch->setIcon(style()->standardIcon(static_cast<QStyle::StandardPixmap>(QStyle::SP_CustomBase + 0x1f))); // menu
    actionStartStop->setIcon(style()->standardIcon(static_cast<QStyle::StandardPixmap>(QStyle::SP_CustomBase + 0x2f))); // timer
    actionLap      ->setIcon(style()->standardIcon(static_cast<QStyle::StandardPixmap>(QStyle::SP_CustomBase + 0x38))); // reload
    actionClear    ->setIcon(style()->standardIcon(static_cast<QStyle::StandardPixmap>(QStyle::SP_CustomBase + 0x0b))); // delete

#ifdef QT_SOFTKEYS_ENABLED
    actionExit->setSoftKeyRole(QAction::NegativeSoftKey);
    actionStopWatch->setSoftKeyRole(QAction::PositiveSoftKey);
#endif

    addAction(actionExit);
    addAction(actionStopWatch);
    addAction(actionStartStop);
    addAction(actionLap);
    addAction(actionClear);

    actionStopWatch->setMenu(new QMenu(this));
    actionStopWatch->menu()->addAction(actionStartStop);
    actionStopWatch->menu()->addAction(actionLap);
    actionStopWatch->menu()->addAction(actionClear);
    actionStopWatch->menu()->addAction(actionExit);

    actionLap->setEnabled(false);

    laps_list->horizontalHeader()->setMovable(false);
    laps_list->horizontalHeader()->setResizeMode(QHeaderView::Fixed);
    connect(this, SIGNAL(hasLaps(bool)), laps_list->horizontalHeader(), SLOT(setVisible(bool)));

    timer.setInterval(11);
    timer.setSingleShot(false);
    connect(&timer, SIGNAL(timeout()), SLOT(updateTimer()));

#ifdef Q_OS_SYMBIAN
    connect(QApplication::desktop(), SIGNAL(workAreaResized(int)), SLOT(workAreaResized(int)));
#endif

    clearTimer();
}

void MainWindow::setOrientation(ScreenOrientation orientation)
{
#ifdef Q_OS_SYMBIAN
    // If the version of Qt on the device is < 4.7.2, that attribute won't work
    if (orientation != ScreenOrientationAuto) {
        const QStringList v = QString::fromAscii(qVersion()).split(QLatin1Char('.'));
        if (v.count() == 3 && (v.at(0).toInt() << 16 | v.at(1).toInt() << 8 | v.at(2).toInt()) < 0x040702) {
            qWarning("Screen orientation locking only supported with Qt 4.7.2 and above");
            return;
        }
    }
#endif // Q_OS_SYMBIAN

    Qt::WidgetAttribute attribute;
    switch (orientation) {
#if QT_VERSION < 0x040702
    // Qt < 4.7.2 does not yet have the Qt::WA_*Orientation attributes
    case ScreenOrientationLockPortrait:
        attribute = static_cast<Qt::WidgetAttribute>(128);
        break;
    case ScreenOrientationLockLandscape:
        attribute = static_cast<Qt::WidgetAttribute>(129);
        break;
    default:
    case ScreenOrientationAuto:
        attribute = static_cast<Qt::WidgetAttribute>(130);
        break;
#else // QT_VERSION < 0x040702
    case ScreenOrientationLockPortrait:
        attribute = Qt::WA_LockPortraitOrientation;
        break;
    case ScreenOrientationLockLandscape:
        attribute = Qt::WA_LockLandscapeOrientation;
        break;
    default:
    case ScreenOrientationAuto:
        attribute = Qt::WA_AutoOrientation;
        break;
#endif // QT_VERSION < 0x040702
    };
    setAttribute(attribute, true);
}

void MainWindow::showExpanded()
{
#ifdef Q_OS_SYMBIAN
    showMaximized();
//    showFullScreen();
#elif defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
    showMaximized();
#else
    show();
#endif
}

#ifdef Q_OS_SYMBIAN
void MainWindow::workAreaResized(int screen)
{
    const QRect &workArea = QApplication::desktop()->availableGeometry(screen);
    updateOrientation(workArea.width() > workArea.height());
    QTimer::singleShot(0, this, SLOT(adjustColumns()));
}
#else
void MainWindow::resizeEvent(QResizeEvent *event)
{
    const QSize &size = event->size();
    updateOrientation(size.width() > size.height());
    QTimer::singleShot(0, this, SLOT(adjustColumns()));
}
#endif

void MainWindow::updateOrientation(bool horizontal)
{
    dynamic_cast<QBoxLayout*>(centralWidget()->layout())->setDirection(horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom);
}

void MainWindow::adjustColumns(void)
{
    laps_list->setColumnWidth(0, laps_list->width()/2);
}

static QString timeToString(qint64 value)
{
    static char time_str[]="HH:MM:SS.mmm";
    time_str[11] = '0'+(value%10); value/=10;
    time_str[10] = '0'+(value%10); value/=10;
    time_str[ 9] = '0'+(value%10); value/=10;
    time_str[ 7] = '0'+(value%10); value/=10;
    time_str[ 6] = '0'+(value% 6); value/= 6;
    time_str[ 4] = '0'+(value%10); value/=10;
    time_str[ 3] = '0'+(value% 6); value/= 6;
    time_str[ 1] = '0'+(value%10); value/=10;
    time_str[ 0] = '0'+(value%10); //value/=10;
    return QString::fromAscii(time_str);
}

void MainWindow::startTimer(bool start)
{
    if (start)
    {
        actionStartStop->setText("Stop");
        stackedWidget->setCurrentWidget(page_lap);
        lap.start();
        timer.start();
    }
    else
    {
        timer.stop();
        addLap();
        time_button->setText(timeToString(elapsed));
        lap.invalidate();
        stackedWidget->setCurrentWidget(page_clear);
        actionStartStop->setText("Start");
    }
}

void MainWindow::updateTimer(void)
{
    time_button->setText(timeToString(elapsed + lap.elapsed()));
}

void MainWindow::clearTimer(void)
{
    lap.invalidate();
    elapsed = 0;
    time_button->setText(QLatin1String("00:00:00.000"));
    laps_list->clearContents();
    laps_list->setRowCount(0);
    emit hasLaps(false);
}

void MainWindow::addLap(void)
{
    quint64 last_lap = lap.restart();
    elapsed += last_lap;

    laps_list->setColumnWidth(0, laps_list->width()/2);

    emit hasLaps(true);

    int row = laps_list->rowCount();
    laps_list->setRowCount(row + 1);

    QTableWidgetItem *item = new QTableWidgetItem(timeToString(elapsed));
    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom);
    laps_list->setItem(row, 0, item);

    item = new QTableWidgetItem(timeToString(last_lap));
    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom);
    laps_list->setItem(row, 1, item);

    laps_list->scrollToBottom();
}
